package com.sdy.healthcode.h5.controller.recorder;

import com.sdy.common.model.BizException;
import com.sdy.common.model.Response;
import com.sdy.common.utils.Assert;
import com.sdy.common.utils.DateUtil;
import com.sdy.common.utils.DesensitizeUtil;
import com.sdy.common.utils.StringUtil;
import com.sdy.healthcode.biz.dto.Address;
import com.sdy.healthcode.biz.dto.FamilyMember;
import com.sdy.healthcode.biz.dto.UserActionPost;
import com.sdy.healthcode.biz.model.*;
import com.sdy.healthcode.biz.param.UpdatePersonnelParam;
import com.sdy.healthcode.biz.service.*;
import com.sdy.healthcode.h5.vo.FamilyMemberVO;
import com.sdy.healthcode.h5.vo.ScanUserInfoVO;
import com.sdy.mvc.controller.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;

@Slf4j
@Controller
@RequestMapping("/recorder")
@Api(tags = "扫码者相关接口")
public class RecorderController extends BaseController {
    @Autowired
    private HealthCodeService healthCodeService;
    @Autowired
    private UserService userService;
    @Autowired
    private UserActionService userActionService;
    @Autowired
    private ApplyPostService applyPostService;
    @Autowired
    private HsDepartmentService hsDepartmentService;
    @Autowired
    private VehicleRegistrationService vehicleRegistrationService;

    @PostMapping("/recordInfo")
    @ResponseBody
    @ApiOperation(value = "扫码用户信息")
    @ApiImplicitParam(value = "健康码标识", name = "tk", required = true)
    public Response<ScanUserInfoVO> recordInfo(HttpServletRequest request, String tk) throws BizException {
        Integer recorderId = getUserId(request);
        Assert.isNull(tk, "参数不能为空。");
        HealthCode healthCode = healthCodeService.queryHealthCodeByToken(tk);
        Assert.isNull(healthCode, "用户健康码不存在或已过期。");
        if (!userService.checkPriviledgeOfRecord(recorderId, healthCode.getUserId())) {
            return Response.error("没有访问权限。");
        }
        User user = userService.getById(healthCode.getUserId());
        Assert.isNull(user, "用户不存在。");
        Integer count = userActionService.countUserAction(user.getId());
        ApplyPost applyPost = applyPostService.queryApplyPost(user.getId());
        Assert.isNull(applyPost, "找不到用户预约记录。");
        ScanUserInfoVO vo = formatScanUserInfo(user, healthCode, applyPost);
        vo.setRecordCount(count);
        return Response.success(vo);
    }

    @PostMapping("/takeRecord")
    @ResponseBody
    @ApiOperation(value = "记录用户行为")
    @ApiImplicitParam(value = "健康码标识", name = "tk", required = true)
    public Response takeRecord(HttpServletRequest request, String tk, @RequestBody UserActionPost userActionPost) throws BizException {
        Integer recorderId = getUserId(request);
        Assert.isNull(tk, "参数不能为空。");
        Assert.isNull(userActionPost, "参数不能为空。");
        Assert.isNull(userActionPost.getAction(), "参数action不能为空。");
        Assert.isNull(userActionPost.getHealthStatus(), "参数healthStatus不能为空。");
        if (userActionPost.getStrategy() == null) {
            userActionPost.setStrategy(1);
        }
        HealthCode healthCode = healthCodeService.queryHealthCodeByToken(tk);
        Assert.isNull(healthCode, "用户健康码不存在或已过期。");
        if (!userService.checkPriviledgeOfRecord(recorderId, healthCode.getUserId())) {
            return Response.error("没有访问权限。");
        }
        User user = userService.getById(healthCode.getUserId());
        Assert.isNull(user, "用户不存在。");
        userActionPost.setUserId(user.getId());
        userActionPost.setRecorderId(recorderId);
        userActionService.takeAction(userActionPost, healthCode);
        return Response.success();
    }

    @PostMapping("/recordInfoForMe")
    @ResponseBody
    @ApiOperation(value = "扫码用户信息(自己)")
    public Response<ScanUserInfoVO> recordInfoForMe(HttpServletRequest request) throws BizException {
        Integer recorderId = getUserId(request);
        HealthCode healthCode = healthCodeService.queryHealthCode(recorderId);
        Assert.isNull(healthCode, "用户健康码不存在或已过期。");
        User user = userService.getById(healthCode.getUserId());
        Assert.isNull(user, "用户不存在。");
        Integer count = userActionService.countUserAction(user.getId());
        ApplyPost applyPost = applyPostService.queryApplyPost(user.getId());
        Assert.isNull(applyPost, "找不到用户预约记录。");
        ScanUserInfoVO vo = formatScanUserInfo(user, healthCode, applyPost);
        vo.setRecordCount(count);
        return Response.success(vo);
    }

    @PostMapping("/takeRecordForMe")
    @ResponseBody
    @ApiOperation(value = "记录用户行为(自己记录)")
    public Response takeRecordForMe(HttpServletRequest request, @RequestBody UserActionPost userActionPost) throws BizException {
        Integer recorderId = getUserId(request);
        HealthCode healthCode = healthCodeService.queryHealthCode(recorderId);
        Integer id;
        if (StringUtil.isNotBlank(userActionPost.getCarNum())) {
            userActionPost.setUserId(recorderId);
            id = vehicleRegistrationService.saveRecord(userActionPost);
            userActionPost.setVehicleId(id);
            // 更新用户信息
            UpdatePersonnelParam updatePersonnelParam = new UpdatePersonnelParam();
            updatePersonnelParam.setId(recorderId).setCarNum(userActionPost.getCarNum());
            userService.updatePersonnel(updatePersonnelParam);
        }

        Assert.isNull(healthCode, "用户健康码不存在或已过期。");
        Assert.isNull(userActionPost, "参数不能为空。");
        Assert.isNull(userActionPost.getAction(), "参数action不能为空。");
        Assert.isNull(userActionPost.getHealthStatus(), "参数healthStatus不能为空。");
        if (userActionPost.getStrategy() == null) {
            userActionPost.setStrategy(1);
        }
        userActionPost.setUserId(recorderId);
        userActionPost.setRecorderId(recorderId);
        userActionService.takeAction(userActionPost, healthCode);
        return Response.success();
    }

    private ScanUserInfoVO formatScanUserInfo(User user, HealthCode healthCode, ApplyPost applyPost) {
        Address address = Address.fromStrToSingleAddr(user.getAddr());
        List<FamilyMember> familyMember = FamilyMember.fromStr(applyPost.getFamilyMember());
        List<FamilyMemberVO> familyMemberVoList = new ArrayList<>();
        for (FamilyMember member : familyMember) {
            User f1 = userService.getUserByPhone(member.getPhone());
            Address addr = f1 == null ? null : Address.fromStrToSingleAddr(f1.getAddr());
            familyMemberVoList.add(new FamilyMemberVO()
                    .setName(f1 == null ? member.getName() : f1.getName())
                    .setPhone(member.getPhone())
                    .setAddr(addr == null ? "" : addr.getArea() + " " + addr.getAddr())
                    .setCardId(f1 == null ? "" : DesensitizeUtil.hideIdCardNo(f1.getCardId())));
        }
        Date now = new Date();
        ScanUserInfoVO scanInfo = new ScanUserInfoVO()
                .setName(user.getName())
                .setAppointmentTime(applyPost.getAppointmentTime())
                .setAppointmentToday(applyPost.getType().equals(3) || applyPost.getAppointmentTime() != null
                        && DateUtil.formatDate(applyPost.getAppointmentTime()).equals(DateUtil.formatDate(now)))
                .setCardType(user.getCardType())
                .setCardId(DesensitizeUtil.hideIdCardNo(user.getCardId()))
                .setPhone(DesensitizeUtil.hideCellPhone(user.getPhone()))
                .setType(healthCode.getType())
                .setIdCardImg(StringUtil.isBlank(applyPost.getIdCardImg())
                        ? Collections.emptyList()
                        : Arrays.asList(applyPost.getIdCardImg().split(";")))
                .setFamilyMember(familyMemberVoList)
                .setAddrLocal(address == null ? "" : address.getArea() + " " + address.getAddr())
                .setPeopleType(user.getPeopleType())
                .setCarNum(user.getCarNum());
        if (healthCode.getType().equals(3) && user.getHsDepartmentId() != null) {
            HsDepartment dept = hsDepartmentService.getById(user.getHsDepartmentId());
            if (dept != null) {
                HsDepartment dept2 = hsDepartmentService.getById(dept.getParentId());
                scanInfo.setHsDepartment((dept2 == null ? "" : dept2.getName() + " ")
                        + dept.getName());
            }
        }
        return scanInfo;

    }
}
